package com.huiquan.management.service;

import java.io.OutputStream;
import java.math.BigDecimal;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.TreeMap;

import javax.servlet.http.HttpServletResponse;

import org.apache.commons.lang.StringUtils;
import org.apache.poi.ss.usermodel.Cell;
import org.apache.poi.ss.usermodel.Row;
import org.apache.poi.ss.usermodel.Sheet;
import org.apache.poi.ss.usermodel.Workbook;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.web.servlet.ModelAndView;

import com.huiquan.foundation.service.UserRecordService;
import com.huiquan.framework.base.BaseService;
import com.huiquan.framework.utils.DateUtils;
import com.huiquan.framework.utils.RespHeaderUtil;
import com.huiquan.onlineTime.dao.OnlineTimeDailyDao;
import com.huiquan.onlineTime.domain.OnlineTimeDailyDto;

@Service
public class OnlineTimeStatisticService extends BaseService {

	private static int DAYS = 7;

	@Autowired
	private OnlineTimeDailyDao onlineTimeDailyDao;
	@Autowired
	private UserRecordService userRecordService;

	private String[] getStartDateAndEndDate(int weekCount) {
		SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd");
		Calendar c = Calendar.getInstance();
		String[] startAndEnd = new String[4];
		c.setTime(new Date());
		c.add(Calendar.DATE, -DAYS * weekCount);
		startAndEnd[0] = format.format(c.getTime());
		c.add(Calendar.DATE, 1);
		startAndEnd[2] = format.format(c.getTime());
		c.clear();
		c.setTime(new Date());
		c.add(Calendar.DATE, -DAYS * (weekCount - 1));
		startAndEnd[1] = format.format(c.getTime());
		c.add(Calendar.DATE, 1);
		startAndEnd[3] = format.format(c.getTime());
		return startAndEnd;
	}

	public ModelAndView onlineTimeStatisticList(String type) {
		type = StringUtils.isNotBlank(type) ? type : "1";
		String endDate = "";
		String startCreateDate = "";
		String endCreateDate = "";
		String[] startAndEnd = null;
		switch (type) {
		// 前2周
		case "2":
			startAndEnd = getStartDateAndEndDate(2);
			break;
		// 前2周
		case "3":
			startAndEnd = getStartDateAndEndDate(3);
			break;
		case "4":
			startAndEnd = getStartDateAndEndDate(4);
			break;
		default:
			startAndEnd = getStartDateAndEndDate(1);
			break;
		}
		if (startAndEnd != null) {
			endDate = startAndEnd[1];
			startCreateDate = startAndEnd[2];
			endCreateDate = startAndEnd[3];
		}
		// 获取前8天的统计数据
		List<OnlineTimeDailyDto> dailyList = onlineTimeDailyDao.retrieveListInDays(startCreateDate, endCreateDate);

		Map<Long, String[]> resultMap = new TreeMap<>();
		Map<Long, String[]> resultCountMap = new TreeMap<>();

		Map<String, Integer> dateRow = new HashMap<>(); // key:yyyy-MM-dd格式的日期字符串;value:在列表中是第几列

		// 标题行，记录日期
		String[] title = new String[DAYS + 1];
		title[0] = "";

		Calendar calendar = Calendar.getInstance();
		// 将日期排序，记录标题行
		for (int i = 1; i < DAYS + 1; i++) {
			Date end = DateUtils.convertDateText(endDate, DateUtils.DateFormat.DATE);
			calendar.setTime(end);
			calendar.add(Calendar.DAY_OF_MONTH, -i);
			String formatDate = DateUtils.convertDateFormat(calendar.getTime(), DateUtils.DateFormat.DATE);
			dateRow.put(formatDate, DAYS + 1 - i);
			title[DAYS + 1 - i] = formatDate;
		}

		// 遍历统计数据，转换为展现数据
		if (dailyList != null && dailyList.size() > 0) {
			for (OnlineTimeDailyDto t : dailyList) {
				String[] result = resultMap.get(t.getUid());
				String[] resultCount = resultCountMap.get(t.getUid());
				if (result == null) {
					result = new String[DAYS + 1];
					resultCount = new String[DAYS + 1];
					result[0] = t.getUserName();
					resultCount[0] = t.getUserName();
					for (int i = 1; i < DAYS + 1; i++) {
						result[i] = "-";
						resultCount[i] = "-";
					}
					resultMap.put(t.getUid(), result);
					resultCountMap.put(t.getUid(), resultCount);
				}
				// 获取记录的时间
				String recordStr = DateUtils.convertDateFormat(DateUtils.getPreNDate(t.getGmtCreated(), 1),
						DateUtils.DateFormat.DATE);
				result[dateRow.get(recordStr)] = DateUtils.formatTimeMillis(t.getMs().longValue());
				Long count = userRecordService.getCountByDate(t.getUid(), DateUtils.getPreNDate(t.getGmtCreated(), 1));
				if (count != null) {
					resultCount[dateRow.get(recordStr)] = count + "";
				}
			}
		}
		List<String[]> resultList = new ArrayList<>();
		resultList.addAll(resultMap.values());
		List<String[]> resultCountList = new ArrayList<>();
		resultCountList.addAll(resultCountMap.values());
		Map<String, Object> map = new HashMap<>();
		map.put("title", title);
		map.put("list", resultList);
		map.put("countList", resultCountList);
		return new ModelAndView("management/index", map);
	}

	public void export(HttpServletResponse resp) throws Exception {

		RespHeaderUtil.setXlsxResp(resp, "实习生计时统计");
		Map<String, Object> param = new HashMap<>();
		// 根据当天日期添加起止日期
		param.put("endDate", getEndDateStr());
		param.put("stateDate", getStartDateStr());
		List<Map<String, Object>> monthlyTotal = onlineTimeDailyDao.retrieveMonthlyTotal(param);

		Workbook workbook = new XSSFWorkbook(); // 创建文档
		Sheet sheet = workbook.createSheet(); // 创建Sheet

		// 标题
		Row title = sheet.createRow(0);
		Cell t1 = title.createCell(0);
		t1.setCellValue("姓名");
		Cell t2 = title.createCell(1);
		t2.setCellValue("工时（单位：小时）");

		// 写入文件
		int i = 1;
		for (Map<String, Object> line : monthlyTotal) {
			Row row = sheet.createRow(i);
			Cell cell1 = row.createCell(0);
			cell1.setCellValue(line.get("name").toString());
			Cell cell2 = row.createCell(1);
			BigDecimal time = new BigDecimal(line.get("time").toString());
			cell2.setCellValue(time.setScale(2, BigDecimal.ROUND_HALF_UP).toString());
			i++;
		}

		OutputStream os = resp.getOutputStream();
		workbook.write(os);

		os.close();
		workbook.close();
	}

	private Object getStartDateStr() {

		Calendar start = Calendar.getInstance();
		start.set(Calendar.DATE, 1);
		start.add(Calendar.MONTH, -1);

		return DateUtils.formatCalendarDate(start);
	}

	private String getEndDateStr() {

		Calendar end = Calendar.getInstance();
		
		end.set(Calendar.DAY_OF_MONTH, 1);
		end.add(Calendar.DATE, -1);

		return DateUtils.formatCalendarDate(end);
	}
}
